#include "bindings/bindings_file_asset_loader.h"
#include "helpers/general.h"
#include "models/file_asset_loader.h"

namespace ohos_rive {
napi_value FileAssetLoaderCreate(napi_env env, napi_callback_info info)
{
    size_t argc = 1;
    napi_value args[1];
    napi_value thisArg;
    void *data;

    napi_get_cb_info(env, info, &argc, args, &thisArg, &data);

    if (argc < 1) {
        napi_throw_error(env, nullptr, "FileAssetLoader constructor requires an ETS object parameter");
        return nullptr;
    }

    napi_valuetype valueType;
    napi_typeof(env, args[0], &valueType);
    if (valueType != napi_object) {
        napi_throw_error(env, nullptr, "FileAssetLoader requires a JavaScript object");
        return nullptr;
    }

    LOGI("Napi_FileAssetLoader_constructor: Creating FileAssetLoader with ETS object");
    FileAssetLoader *fileAssetLoader = new FileAssetLoader(env, args[0]);
    if (!fileAssetLoader) {
        napi_throw_error(env, nullptr, "Failed to create FileAssetLoader instance");
        return nullptr;
    }

    napi_value result;
    napi_status status = napi_create_int64(env, reinterpret_cast<int64_t>(fileAssetLoader), &result);
    if (status != napi_ok) {
        delete fileAssetLoader;
        napi_throw_error(env, nullptr, "Failed to create return value");
        return nullptr;
    }

    LOGI("Napi_FileAssetLoader_constructor: Successfully created FileAssetLoader, pointer: %{public}p",
         fileAssetLoader);
    return result;
}

napi_value FileAssetLoaderDelete(napi_env env, napi_callback_info info)
{
    size_t argc = 1;
    napi_value args[1];
    napi_value thisArg;
    void *data;

    napi_get_cb_info(env, info, &argc, args, &thisArg, &data);

    if (argc < 1) {
        LOGE("Wrong number of arguments");
        return nullptr;
    }

    int64_t pointerValue;
    napi_status status = napi_get_value_int64(env, args[0], &pointerValue);
    if (status != napi_ok) {
        LOGE("Invalid pointer argument");
        return nullptr;
    }

    auto *fileAssetLoader = reinterpret_cast<FileAssetLoader *>(pointerValue);
    if (fileAssetLoader) {
        LOGI("FileAssetLoader unref: %{public}p", fileAssetLoader);
        fileAssetLoader->unref();
    }

    napi_value result;
    napi_get_undefined(env, &result);
    return result;
}

napi_value FileAssetLoaderRef(napi_env env, napi_callback_info info)
{
    size_t argc = 1;
    napi_value args[1];
    napi_value thisArg;
    void *data;

    napi_get_cb_info(env, info, &argc, args, &thisArg, &data);

    if (argc < 1) {
        LOGE("Wrong number of arguments");
        return nullptr;
    }

    int64_t pointerValue;
    napi_status status = napi_get_value_int64(env, args[0], &pointerValue);
    if (status != napi_ok) {
        LOGE("Invalid pointer argument");
        return nullptr;
    }

    auto *fileAssetLoader = reinterpret_cast<FileAssetLoader *>(pointerValue);
    if (fileAssetLoader) {
        fileAssetLoader->ref();
    }

    napi_value result;
    napi_get_undefined(env, &result);
    return result;
}

napi_value FileAssetLoaderSetRendererType(napi_env env, napi_callback_info info)
{
    size_t argc = 2;
    napi_value args[2];
    napi_value thisArg;
    void *data;

    napi_get_cb_info(env, info, &argc, args, &thisArg, &data);

    if (argc < 2) {
        LOGE("Wrong number of arguments");
        return nullptr;
    }

    int64_t pointerValue;
    napi_status status = napi_get_value_int64(env, args[0], &pointerValue);
    if (status != napi_ok) {
        LOGE("Invalid pointer argument");
        return nullptr;
    }

    int32_t rendererType;
    napi_get_value_int32(env, args[1], &rendererType);

    auto *fileAssetLoader = reinterpret_cast<FileAssetLoader *>(pointerValue);
    if (fileAssetLoader) {
        fileAssetLoader->setRendererType(static_cast<RendererType>(rendererType));
    }

    napi_value result;
    napi_get_undefined(env, &result);
    return result;
}
} // namespace ohos_rive